#pragma once

#include <QString>
#include <QObject>
#include <QHash>
#include "deviceactor.h"
#include "uniformmotion.h"
#include "professionpropertydefine.h"
#include "fadeeffect.h"
#include "templateclass.h"
#include <osg\ref_ptr>
#include <QTimer>
#include <QMutex>
#include "port3dapi_global.h"

class ObjectEntitiesArray;
class ObjectEntities;
class DoubleArray;
class PositionArray;

class PORT3DAPI_EXPORT  DynamicDataCacheManager:QObject
{
	Q_OBJECT
public:
	struct DynamicObjectData
	{
		ObjectEntities*											_object;
		osg::ref_ptr<VrDataCore::DeviceActor>					_deviceActor;
		VrDataCore::DeviceActor*								_resourceActor;
		osg::ref_ptr<VrDataCore::MotionEffect>					_motionEffect;
		osg::ref_ptr<VrDataCore::ProfessionPropertyDefine>		_professionProperty;
		bool													_removeRequest;
	};
	DynamicDataCacheManager();
	~DynamicDataCacheManager();

	void updatePosition(ObjectEntitiesArray* entitiesarray);
	bool deleteObject(const QString& id);
	void setStaticDynamicData(ObjectEntities* entities);
	void showDeviceDataWidget(ObjectEntities* entities);
	void hideDeviceDataWidget();
	void clearAll();
	void mapChanged();
	template<typename T,typename P>
	void registerObjectCreateCallback(const QString& key,void (T::*function)(P),T* obj,P p)
	{
		osg::ref_ptr<FuncBase> newfunc = new Type_1Func<void,T,osg::ref_ptr<CoreBase::ActorBase>>(function,obj,p);
		_createFuncMap.insert(key,newfunc);
	}
	template<typename T,typename P>
	void registerObjectDeleteCallback(const QString& key,void (T::*function)(P),T* obj,P p)
	{
		osg::ref_ptr<FuncBase> newfunc = new Type_1Func<void,T,osg::ref_ptr<CoreBase::ActorBase>>(function,obj,p);
		_deleteFuncMap.insert(key,newfunc);
	}
	void showTarget(int type, int subtype,bool state);
	bool createAutoMoveObjectWithTrack(ObjectEntities* entities, PositionArray* p,DoubleArray* t,bool loop);
	bool createAutoUniformMoveObjectWithTrack(ObjectEntities* entities, PositionArray* p,double speed,bool loop);
	void createOrUpdateObjects_2(const QString& shipid,const QString& mmsi,const QString& imo,const QString& type,
		const QString& name,double lng,double lat,const QString& callsign,double beam,const QString& cargotype,
		const QString& country,double course,const QString& dest,double draught,const QString& eta,double heading,
		double lasttime,double left,double length,double rot,double speed,const QString& status,double trail);
	void createOrUpdateObjects_3(const QStringList& datalist);
protected:
	void create(DynamicObjectData* data);
	void update(DynamicObjectData* data);
	//void remove(DynamicObjectData* data);
	void callObjectCreateFun(osg::ref_ptr<CoreBase::ActorBase> p);
	void callObjectDeleteFun(osg::ref_ptr<CoreBase::ActorBase> p);
private:
	QHash<QString,DynamicObjectData*>											_dynamicObjectsPosMap;
	QHash<QString,DynamicObjectData>											_objectsPropertyMap;
	QHash<QString,DynamicObjectData*>											_autoMoveObjectMap;
	osg::Vec3																	_environmentPos;
	QString																		_currentPropertyWidgetId;
	osg::Vec3																	_surroundMin;
	osg::Vec3																	_surroundMax;
	QHash<QString,osg::ref_ptr<FuncBase>>										_createFuncMap;
	QHash<QString,osg::ref_ptr<FuncBase>>										_deleteFuncMap;
	QTimer																		_timer;
	unsigned int																_updateInterval;
	QHash<QString,DynamicObjectData*>											_waitObjectDataMap;
	QVector<DynamicObjectData*>													_defaultNULLObject;
	QMutex																		_ObjectDataVecctorMutex;
private slots:
	void slotsTimeOut();
};